package org.airdroid.scenemix;

import android.app.Fragment;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;

public class LevelMeterFragment extends Fragment {
	AudioInputTask inputTask;
	LevelView[] levels = new LevelView[12];

	@Override
	public View onCreateView(LayoutInflater inflater, ViewGroup container,
			Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		View root = inflater.inflate(R.layout.levelmeter, container);

		levels[0] = (LevelView)root.findViewById(R.id.levelView1);
		levels[1] = (LevelView)root.findViewById(R.id.levelView2);
		levels[2] = (LevelView)root.findViewById(R.id.levelView3);
		levels[3] = (LevelView)root.findViewById(R.id.levelView4);
		levels[4] = (LevelView)root.findViewById(R.id.levelView5);
		levels[5] = (LevelView)root.findViewById(R.id.levelView6);
		levels[6] = (LevelView)root.findViewById(R.id.levelView7);
		levels[7] = (LevelView)root.findViewById(R.id.levelView8);
		levels[8] = (LevelView)root.findViewById(R.id.levelView9);
		levels[9] = (LevelView)root.findViewById(R.id.levelView10);
		levels[10] = (LevelView)root.findViewById(R.id.levelView11);
		levels[11] = (LevelView)root.findViewById(R.id.levelView12);

		inputTask = new AudioInputTask();
		inputTask.execute();
		
		return root;
	}
	
	@Override
	public void onDestroyView() {
		inputTask.stop();
		
		super.onDestroyView();
	}

	// cf. http://www.java2s.com/Code/Android/Media/UsingAudioRecord.htm
	private class AudioInputTask extends AsyncTask<Void, Integer, Void> {
		boolean isRecording = false;
		int frequency = 11025;
		int channelConfiguration = AudioFormat.CHANNEL_CONFIGURATION_MONO;
		int audioEncoding = AudioFormat.ENCODING_PCM_16BIT;

		@Override
		protected Void doInBackground(Void... params) {
			android.os.Process.setThreadPriority(
			          android.os.Process.THREAD_PRIORITY_URGENT_AUDIO);

			isRecording = true;
			try {
				int bufferSize = AudioRecord.getMinBufferSize(frequency,
						channelConfiguration, audioEncoding);
				AudioRecord audioRecord = new AudioRecord(
						MediaRecorder.AudioSource.MIC, frequency,
						channelConfiguration, audioEncoding, bufferSize);

				short[] buffer = new short[bufferSize];
				audioRecord.startRecording();
				int r = 0;
				while (isRecording) {
					int bufferReadResult = audioRecord.read(buffer, 0, bufferSize);
					int max = 0;
					
					for (int i = 0; i < bufferReadResult; i++) {
						int v = buffer[i];
						v = (v < 0) ? -v : v;
						v = (v >> 7) & 0xff;
						if (max < v) {
							max = v;
						}
					}
					publishProgress(new Integer(max));
					r++;
				}
				audioRecord.stop();
			} catch (Throwable t) {
				Log.e("AudioInputTask", "Recording Failed");
			}
			return null;
		}
		
		protected void onProgressUpdate(Integer... progress) {
			Log.d("AudioInputTask", "max : " + progress[0].toString());
			
			for (int i = 0; i < 11; i++) {
				levels[i].setLevel(levels[i + 1].getLevel());
			}
			levels[11].setLevel(progress[0] * 9 / 256);
		}
		
		protected void onPostExecute(Void result) {
		}
		
		public void stop() {
			isRecording = false;
		}
	}
}
